package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.service.AuditService;
import com.atguigu.tingshu.album.service.FileUploadService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.Map;

@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {
    @Autowired
    private MinioClient minioClient;
    @Autowired
    private MinioConstantProperties minioConstantProperties;
    @Autowired
    private VodConstantProperties vodConstantProperties;
    @Autowired
    private VodUploadClient vodUploadClient;
    @Autowired
    private AuditService auditService;

    /**
     * 图片文件上传
     *
     * @param file 图片文件
     * @return minioConstantProperties.getEndpointUrl()+"/"+minioConstantProperties.getBucketName()+objectName
     * @拼接图片在线访问地址
     */
    @Override
    public String fileUpload(MultipartFile file) throws Exception {
        //1 校验文件格式
        //使用hutool工具api
        BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
        if (bufferedImage == null) {
            throw new GuiguException(500, "文件格式错误");
        }
        //2 校验文件大小
        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        if (width > 1500 || height > 1500) {
            throw new GuiguException(500, "上传文件过大");
        }
//        服务暂停 //图片内容审核
//        String suggestion = auditService.auditImage(file);
//        if ("block".equals(suggestion)||"review".equals(suggestion)){
//            throw new GuiguException(500,"图片内容违规,请重新上传");
//        }
        //3 生成文件标识
        String folder = "/" + DateUtil.today();
        String fileName = IdUtil.randomUUID();
        String extName = FileNameUtil.extName(file.getOriginalFilename());
        String objectName = folder + "/" + fileName + "." + extName;
        //4 创建minio客户端
        //注意: 需要同步quest和minio服务器宿主机的时间(使用ntp服务)
        try {
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(minioConstantProperties.getBucketName()).object(objectName).stream(
                                    file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
        } catch (Exception e) {
            throw new GuiguException(500, "文件上传失败");
        }
        //5 构造返回结果url
        return minioConstantProperties.getEndpointUrl() + "/" + minioConstantProperties.getBucketName() + objectName;
    }

    /**
     * 声音文件上传
     *
     * @param file 声音文件
     * @return Map<mediaId, mediaUrl> 声音媒体ID及在线访问URL
     */
    @Override
    public Map<String, String> uploadTrack(MultipartFile file) {
        try {
            //1.将上传文件保存到本地得到文件路径,后续采用定时任务清理临时目录下使用完毕文件
            String filePath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
            //2.构造上传请求对象:设置媒体本地上传路径
            VodUploadRequest request = new VodUploadRequest();
            request.setMediaFilePath(filePath);
            //3.调用上传方法，传入接入点地域及上传请求。
            VodUploadResponse response = vodUploadClient.upload(vodConstantProperties.getRegion(), request);
            //4.获取在线媒体资源信息
            if (response != null) {
                String mediaId = response.getFileId();
                String mediaUrl = response.getMediaUrl();
                return Map.of("mediaFileId", mediaId, "mediaUrl", mediaUrl);
            }
            return null;
        } catch (Exception e) {
            log.error("上传文件失败", e);
            throw new RuntimeException(e);
        }
    }
}
